gRPC 是一个功能强大、高性能的远程过程调用 (RPC) 框架,尽管不如 REST 常用,但在某些场景中提供了显着的优势。
此外,它与语言无关,可以在任何环境中运行,使其成为服务器到服务器通信的理想选择。
我不会深入研究它的完整解释,但这里是 gRPC 的一般链接。我将提供实践教程
让我们想象一下,我们的 Go 是客户端,但对于前端应用程序 React、Svelte 等来说,它是服务器。
func getFirstArg() (string, error) { if len(os.Args)作为示例,React 前端上传一个文件,Go 处理它,但我们需要来自 excel 的答案,我们将使用 GPT API。虽然可以用 Go 来完成,但另一方面 Python 有更多可以简化我们生活的软件包,例如 langchan_openai、pandas for excel 等等。
我们首先最好在您的 virtualenv .venv 中安装 gRPC
$ go install google.golang.org/protobuf/cmd/protoc-gen-go@latest $ go install google.golang.org/grpc/cmd/protoc-gen-go-grpc@latest $ export PATH="$PATH:$(go env GOPATH)/bin"接下来你应该在你的操作系统中安装protocol buffer,可以在此处安装。
让我们创建一个 proto 目录,您将在其中存储协议缓冲区文件,我将其命名为 excel.proto 并粘贴此:syntax = "proto3"; option go_package = "client-gRPC/proto"; service ExcelService { rpc UploadFile(FileRequest) returns (FileResponse); } message FileRequest { string file_name = 1; bytes file_content = 2; } message FileResponse { bytes file_content = 1; }这个 gRPC 服务 ExcelService 允许客户端通过发送文件名称和内容来上传文件。服务器以相同的文件内容进行响应。
对于 Go,在 Python 中传递 go_package 是必需的,不需要这一行。
如果您使用 VSCode,vscode-proto3 是一个很好的下载扩展。
完成所有这些之后,您可以生成原型文件,我更喜欢它与 prot 目录处于同一级别,为此运行此命令:
协议--go_out=。 --go_opt=paths=source_relative --go-grpc_out=. --go-grpc_opt=paths=source_relative proto/excel.proto
如果成功生成两个文件,如果需要进行大量调整,则可以选择添加一个 Makefile 并将其定义为 proto 上命令。
import ( .... "google.golang.org/grpc" pb "client-gRPC/proto" "github.com/xuri/excelize/v2" ) func main() { .... conn, err := grpc.Dial("localhost:50051", grpc.WithInsecure()) if err != nil { log.Fatalf("Failed to connect to gRPC server: %v", err) } defer conn.Close() client := pb.NewExcelServiceClient(conn) req := &pb.FileRequest{ FileName: filePath, FileContent: fileData, } res, err := client.UploadFile(context.Background(), req) if err != nil { log.Fatalf("Failed to upload file: %v", err) } outputFile := "output.xlsx" err = saveBytesAsExcel(outputFile, res.FileContent) if err != nil { log.Fatalf("Failed to save bytes as Excel file: %v", err) } fmt.Printf("Excel file saved as: %s\n", outputFile) } func saveBytesAsExcel(filePath string, fileContent []byte) error { f, err := excelize.OpenReader(bytes.NewReader(fileContent)) if err != nil { return fmt.Errorf("failed to open Excel file: %v", err) } if err := f.SaveAs(filePath); err != nil { return fmt.Errorf("failed to save Excel file: %v", err) } return nil }我们建立一个连接来监听 50051,它将成为我们的 Python 服务器,&pb.FileRequest 是之前使用 proto 命令生成的,现在我们正在导入方法。如果你跑步你会收到?由于Python服务器尚未建立。
Failed to upload file: rpc error: code = Unavailable desc = connection error: desc = "transport: Error while dialing: dial tcp 127.0.0.1:50051: connect: connection refused"Python gRPC 服务器
由于 python 将充当服务器,因此方法会略有不同,但本质上不需要包字段中的相同原始文件。让我们首先创建一个不带 gRPC 的基础 main.py,以便了解 GPT 如何填充 excel 中的问题。
import os import openai import pandas as pd from dotenv import load_dotenv def get_answer_from_gpt(apikey: str, question: str): openai.api_key = apikey response = openai.ChatCompletion.create( model="gpt-4", messages=[ {"role": "system", "content": "You are a helpful assistant."}, {"role": "user", "content": question} ] ) return response['choices'][0]['message']['content'].strip() def answer_questions_df(df: pd.DataFrame, apikey: str): answers = [] for question in df.iloc[:, 0]: answer = get_answer_from_gpt(apikey, question) answers.append(answer) return answers if __name__ == "__main__": load_dotenv() openai_api_key = os.getenv("OPENAI_API_KEY", "OpenAI API key hasn't been set.") df = pd.read_excel('Book1.xlsx') df['Answer'] = answer_questions_df(df, openai_api_key这是一个简单的脚本,可以回答 Go 发送给我们的问题,但由于专用的 openai 库,LOC 较少,这使得它变得更容易。
我们首先添加具有与上面相同的文件的原始目录,可以按照讨论删除选项部分。最好在您的 virtualenv 中安装 gRPC,然后按照我运行的原型生成安装“
python3 -m grpc_tools.protoc --proto_path=proto --python_out=proto --grpc_python_out=proto proto/excel.proto与我的原始目录处于相同的lvl 记得添加 __init.py!
文件已生成,让我们继续。
import io import grpc from proto import excel_pb2_grpc as excel_grpc from proto import excel_pb2 class ExcelService(excel_grpc.ExcelServiceServicer): def UploadFile(self, request, context): try: # Convert bytes to a file-like object file_like_object = io.BytesIO(request.file_content) # Load the workbook from the file-like object workbook = openpyxl.load_workbook(file_like_object) # Access the first sheet (or use appropriate logic to get the sheet you need) sheet = workbook.active # Convert the sheet to a DataFrame data = sheet.values columns = next(data) # Get the header row df = pd.DataFrame(data, columns=columns) print("Loaded DataFrame:") print(df.head()) # Ensure that the DataFrame is not empty and has questions if df.empty or df.shape[1]我们定义服务器并添加 ExcelService 类,其中包含 proto 文件生成的方法。因为我们按字节接收文件,所以必须使用 io 字节读取器并开始进一步处理文件并填充第二列。
response = excel_pb2.FileResponse(file_content=output.read())最后我们返回 ☝️ 供 Go 客户端接收。
为了能够在 python 中找到原始文件,您应该定义一个导出路径
导出 PYTHONPATH=$PYTHONPATH:mnt/c/own_dev/gRPC/server/proto
运行客户端和服务器
If all is good you can run #First comes server python3 -m main #Then client go run client.go Book1.xlsx您应该在 Go 客户端获得更新的 .xlsx 文件。
结论
在本文中,我们探讨了在 Python 服务器和 Go 客户端之间设置 gRPC 通信的基础知识。通过利用 gRPC,我们建立了一种无缝方式,将 Excel 文件从 Go 应用程序发送到 Python 服务器,使用 OpenAI 的 GPT API 处理文件,并将修改后的文件返回到 Go 客户端。
免责声明: 提供的所有资源部分来自互联网,如果有侵犯您的版权或其他权益,请说明详细缘由并提供版权或权益证明然后发到邮箱:[email protected] 我们会第一时间内为您处理。
Copyright© 2022 湘ICP备2022001581号-3